
out vec4 FragColor;

in vec2 fragUv;
uniform vec2 pixelSize;

uniform sampler2D colorMap;
uniform sampler2D accumulateMap;

// only RG
uniform sampler2D vectorMap;

vec3 RGBToYCoCg(vec3 color){
    mat3 m = mat3( 0.25,  0.5, 0.25,
            0.5,  0,  -0.5,
            -0.25, 0.5, -0.25);
    return m * color;
}

vec3 YCoCgToRGB(vec3 color){
    mat3 m = mat3(1,  1,  -1,
            1,  0,   1,
            1, -1,  -1);
    return m * color;
}



void main()
{             
    vec2 offset = texture(vectorMap,fragUv).rg;

    offset = offset * 2.0 - 1.0;

    vec2 oldUv = fragUv - offset;
    vec3 currentColor = texture(colorMap,fragUv).rgb;
    vec3 accumulateColor;
    if(any(lessThan(oldUv,vec2(0.0))) || any(greaterThan(oldUv,vec2(1.0)))){
        accumulateColor = currentColor;
    }else{
        accumulateColor = texture(accumulateMap,oldUv).rgb;
    }

    vec3 minN = RGBToYCoCg(currentColor);
    vec3 maxN = minN;

    for(int y = -1; y <=1; ++y){
        for(int x = -1; x <= 1; ++x){
            vec3 n = texture(colorMap, fragUv + vec2(x,y) * pixelSize).rgb;
            n = RGBToYCoCg(n);
            minN = min(minN,n);
            maxN = max(maxN,n);
        }
    }
    accumulateColor = RGBToYCoCg(accumulateColor);
    accumulateColor = clamp(accumulateColor,minN,maxN);
    accumulateColor = YCoCgToRGB(accumulateColor);
    vec3 outputColor = mix(currentColor,accumulateColor,0.95);
    FragColor = vec4(outputColor,1.0);
}